package com.ruike.alisurface.Serials;

import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;

import com.voodoo.lib_utils.ByteUtils;
import com.voodoo.lib_utils.L;

/**
 * Author: voodoo
 * CreateDate: 2023/09/26 026 上午 11:39
 * Description: 反扫
 */
public class ReScanUtils {

    static Handler mainHandler;
    // 是否需要回调结果
    public static boolean isCanCallbackResult = false;
    // 返回数据监听
    static OnReScanListener mOnReScanListener;

    public static void initListener() {
        mainHandler = new Handler(Looper.getMainLooper());
        Ttys1Utils.getInstance().setOnSerialPortResultDataListener((resultDataStr, resultBytes) -> {
            if (!TextUtils.isEmpty(resultDataStr) && resultBytes != null && resultBytes.length > 0) {
                mySerialPortResultData(resultDataStr, resultBytes);
            } else {
                L.e("返回指令异常");
            }
        });
    }

    static StringBuffer resultByteSb;

    private static void mySerialPortResultData(String serialPortData, byte[] resultBytes) {
//        L.i("返回指令：" + serialPortData);

        // 指令操作返回值
        if (resultBytes[0] == 0x02 && resultBytes[1] == 0x00) {
            if (resultBytes[2] == 0x00) {
                L.i("操作成功");
            }
            return;
        }

        if (!isCanCallbackResult) {
            L.i("非启用阶段，不处理");
            return;
        }

        // 如果回传的起始位是符号"{" 0x7B，那么此条回传是起始
        if (resultBytes[0] == 0x7B) {
            L.i("回传头字节数组：" + serialPortData);
            resultByteSb = new StringBuffer();
        }
        if (resultByteSb != null) {
            // 如果之前品结果，在之前的指令结尾加个空格
            if (resultByteSb.length() > 0) {
                resultByteSb.append(" ");
            }
            // 将传入的字符串拼接到原始字符串中
            resultByteSb.append(serialPortData);
            // 判断结尾，如果倒数第二位是符号"}" 0x7D 和 回车换行符 0x0D 或者倒数第三位是符号"}" 0x7D 倒数第一二位是 回车换行符 0x0D 0x0A，那么此条指令是最后的结尾数据
            if ((resultBytes[resultBytes.length - 2] == 0x7D && resultBytes[resultBytes.length - 1] == 0x0D) ||
                    (resultBytes[resultBytes.length - 3] == 0x7D && resultBytes[resultBytes.length - 2] == 0x0D && resultBytes[resultBytes.length - 1] == 0x0A)) {
                String resultByteStr = resultByteSb.toString();
                L.i("回传尾字节数组，整体回传：" + resultByteStr);
                byteArrayToString(resultByteStr);
                resultByteSb = null;
                return;
            }
            L.e("结尾非0x7D 0x0D，数据不全，继续等待...");
        } else {
            L.e("二维码数据格式不正确:" + serialPortData);
            if (mOnReScanListener != null) {
                mainHandler.post(() -> mOnReScanListener.onReScanResultListener(false, "二维码数据格式不正确"));
            }
        }

        // 7B 73 65 73 73 69 6F 6E 49 64 3D 36 35 31 31 30 31 38 31 36 62 36 65 36 39 30 34 34 64 31 65 32
        // 33 61 37 2C 61 63 63 6F 75 6E 74 49 64 3D 36 35 31 31 30 31 38 31 36 62 36 65 36 39 30 34 34 64
        // 31 65 32 33 61 36 7D 0D

    }

    /**
     * @param byteStr
     */
    static void byteArrayToString(String byteStr) {
        byte[] resultBytes = ByteUtils.hexToByteArr(byteStr);
        char[] chars = new char[resultBytes.length];
        for (int i = 0; i < resultBytes.length; i++) {
            chars[i] = (char) Integer.parseInt(ByteUtils.byteToHex(resultBytes[i]), 16);
        }
        String resultStr = String.valueOf(chars);
        L.i("转换后的结果：" + String.valueOf(chars));
        // 对数据结果进行回调
        if (mOnReScanListener != null) {
            mainHandler.post(() -> {
                L.i("扫码结果回调出去");
                mOnReScanListener.onReScanResultListener(true, resultStr);
            });
            return;
        }
        L.i("扫码结果无回调，监听为空");
    }

    /**
     * 设置扫码结束后自动清零
     */
    public static void setIsAutoZeroing(boolean isAutoZeroing) {
        byte[] sendBytes = new byte[7];
        int index = 0;
        sendBytes[index++] = 0x7E; // {Head1}
        sendBytes[index++] = 0x00; // {Head1}
        sendBytes[index++] = 0x08; // {Types}
        sendBytes[index++] = 0x01; // {Lens}
        sendBytes[index++] = 0x00; // {Address} 标志
        sendBytes[index++] = 0x02; // {Address} 位
        sendBytes[index] = (byte) (isAutoZeroing ? 1 : 0); // {Datas} 具体数据位
        String sendByteStr = ByteUtils.byteArrToHex(getCrcCcitt(sendBytes, -1));
        L.i("设置扫码结束后" + (isAutoZeroing ? "自动清零" : "不自动清零") + "指令：" + sendByteStr);
        Ttys1Utils.getInstance().SendPort(sendByteStr);
    }

    /**
     * 开始读取数据
     */
    public static void startReadQrCode() {
        isCanCallbackResult = true;
    }

    /**
     * 结束读取
     */
    public static void stopReadQrCode() {
        isCanCallbackResult = false;
    }

    /**
     * 复位
     */
    public static void reset() {
        byte[] sendBytes = new byte[7];
        int index = 0;
        sendBytes[index++] = 0x7E; // {Head1}
        sendBytes[index++] = 0x00; // {Head1}
        sendBytes[index++] = 0x09; // {Types} 07读  08写
        sendBytes[index++] = 0x01; // {Lens}
        sendBytes[index++] = 0x00; // {Address}
        sendBytes[index++] = 0x00; // {Address}
        sendBytes[index] = (byte) 0xFF; // {Datas}
        String sendByteStr = ByteUtils.byteArrToHex(getCrcCcitt(sendBytes, 2));
        L.i("发送反扫器复位指令：" + sendByteStr);
        Ttys1Utils.getInstance().SendPort(sendByteStr);
    }

    /**
     * 获取 CRC-CCITT 校验值
     *
     * @param bytes      待计算的 byte 数组
     * @param startIndex 计算起始下标，大于等于0，则按照下标计算，否则按照协议中的不计算去处理
     * @return 带校验位的 byte 数组
     */
    private static byte[] getCrcCcitt(byte[] bytes, int startIndex) {
        if (bytes == null || bytes.length <= 0) {
            return bytes;
        }

        byte heightByte = (byte) 0xAB;
        byte lowByte = (byte) 0xBC;

        if (startIndex >= 0) {
            if (startIndex > bytes.length - 1) {
                return bytes;
            }
            byte[] tempBytes = new byte[bytes.length - startIndex];
            System.arraycopy(bytes, startIndex, tempBytes, 0, tempBytes.length);
            byte[] toByteArr = CRC_XModem(tempBytes);
            heightByte = toByteArr[0];
            lowByte = toByteArr[1];
        }

        byte[] resultBytes = new byte[bytes.length + 2];
        System.arraycopy(bytes, 0, resultBytes, 0, bytes.length);
        resultBytes[resultBytes.length - 2] = heightByte;
        resultBytes[resultBytes.length - 1] = lowByte;
        return resultBytes;
    }

    /**
     * CRC16-CCITT(XModem)
     *
     * @param bytes 待计算校验值的字节数组
     * @return 计算完成之后的值
     */
    public static byte[] CRC_XModem(byte[] bytes) {
        int crc = 0x00;
        int polynomial = 0x1021;
        for (int index = 0; index < bytes.length; index++) {
            byte b = bytes[index];
            for (int i = 0; i < 8; i++) {
                boolean bit = ((b >> (7 - i) & 1) == 1);
                boolean c15 = ((crc >> 15 & 1) == 1);
                crc <<= 1;
                if (c15 ^ bit) crc ^= polynomial;
            }
        }
        crc &= 0xffff;
        return ByteUtils.hexToByteArr(Integer.toHexString(crc).toUpperCase());
    }

    public static void setOnReScanListener(OnReScanListener onReScanListener) {
        mOnReScanListener = onReScanListener;
    }

    public interface OnReScanListener {
        /**
         * 扫描返回结果监听
         *
         * @param isSuccess 是否正确，如果不正确，那么第二个参数为错误原因
         * @param content   返回结果字符串
         */
        void onReScanResultListener(boolean isSuccess, String content);
    }

}
